home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / ROM_Kernel_Manuals / Devices / apps / ILBMDemo / ILBMDemo.c
Encoding:
C/C++ Source or Header  |  1992-08-20  |  10.1 KB  |  409 lines

  1. /* ILBMDemo.c  05/91   C. Scheppner CBM
  2.  *
  3.  * Demonstrates displaying an ILBM, loading a brush,
  4.  *   saving an ILBM, and optionally printing a screen (CTRL-p)
  5.  *   Use -c (or -c1, -c2, etc) as filename to read from or save to clipboard.
  6.  *
  7.  * requires linkage with several iffp modules - see Makefile
  8.  */
  9.  
  10. #include "iffp/ilbmapp.h"
  11.  
  12.  
  13. #ifdef LATTICE
  14. int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
  15. int chkabort(void) { return(0); }  /* really */
  16. #endif
  17.  
  18. void chkmsg(void);
  19. void cleanup(void);
  20. void bye(UBYTE *s,int error);
  21.  
  22. #define SAVECHANGES
  23.  
  24. #define MINARGS 3
  25. char *vers = "\0$VER: ILBMDemo 37.5";
  26. char *Copyright = "ILBMDemo v37.5 (Freely Redistributable)";
  27. char *usage =
  28. "Usage: ILBMDemo sourceilbm destilbm [brushname]  (CTRL-p to print screen)\n"
  29. "Displays source, optionally loads and blits brush, saves to dest\n"
  30. "Use filename -c[unit] (ie. -c, -c1, -c2, etc.) for clipboard\n";
  31.  
  32. char *savename;
  33.  
  34. struct Library *IntuitionBase  = NULL;
  35. struct Library *GfxBase        = NULL;
  36. struct Library *IFFParseBase   = NULL;
  37.  
  38. /* Note - these fields are also available in the ILBMInfo structure */
  39. struct   Screen         *scr;         /* for ptr to screen structure */
  40. struct   Window         *win;         /* for ptr to window structure */
  41. struct   RastPort       *wrp;         /* for ptr to RastPort  */
  42. struct   ViewPort       *vp;          /* for ptr to Viewport  */
  43.  
  44. struct   IntuiMessage   *msg;
  45.  
  46. struct   NewWindow      mynw = {
  47.    0, 0,                                  /* LeftEdge and TopEdge */
  48.    0, 0,                                /* Width and Height */
  49.    -1, -1,                                /* DetailPen and BlockPen */
  50.    VANILLAKEY|MOUSEBUTTONS,               /* IDCMP Flags with Flags below */
  51.    BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP,
  52.    NULL, NULL,                            /* Gadget and Image pointers */
  53.    NULL,                                  /* Title string */
  54.    NULL,                                  /* Screen ptr null till opened */
  55.    NULL,                                  /* BitMap pointer */
  56.    50, 20,                                /* MinWidth and MinHeight */
  57.    0 , 0,                                 /* MaxWidth and MaxHeight */
  58.    CUSTOMSCREEN                           /* Type of window */
  59.    };
  60.  
  61.  
  62. BOOL   FromWb, Done;
  63.  
  64.  
  65. /* ILBM Property chunks to be grabbed
  66.  * List BMHD, CMAP and CAMG first so we can skip them when we write
  67.  * the file back out (they will be written out with separate code)
  68.  */
  69. LONG    ilbmprops[] = {
  70.         ID_ILBM, ID_BMHD,
  71.         ID_ILBM, ID_CMAP,
  72.         ID_ILBM, ID_CAMG,
  73.         ID_ILBM, ID_CCRT,
  74.         ID_ILBM, ID_AUTH,
  75.         ID_ILBM, ID_Copyright,
  76.         TAG_DONE
  77.         };
  78.  
  79. /* ILBM Collection chunks (more than one in file) to be gathered */
  80. LONG    ilbmcollects[] = {
  81.         ID_ILBM, ID_CRNG,
  82.         TAG_DONE
  83.         };
  84.  
  85. /* ILBM Chunk to stop on */
  86. LONG    ilbmstops[] = {
  87.         ID_ILBM, ID_BODY,
  88.         TAG_DONE
  89.         };
  90.  
  91.  
  92. /* For test of adding new chunks to saved FORM */
  93. struct Chunk newchunks[2] = {
  94.     {
  95.     &newchunks[1],
  96.     ID_ILBM, ID_AUTH, IFFSIZE_UNKNOWN,
  97.     "CAS_CBM"},
  98.     {
  99.     NULL,
  100.     ID_ILBM, ID_NAME, IFFSIZE_UNKNOWN,
  101.     "Untitled No. 27"},
  102.     };
  103.  
  104.  
  105. UBYTE nomem[]  = "Not enough memory\n";
  106. UBYTE noiffh[] = "Can't alloc iff\n";
  107.  
  108. /* our indexes to reference our frames
  109.  * DEFault, BRUsh, and SCReen
  110.  */
  111. #define DEF    0
  112. #define BRU    1
  113. #define SCR    2
  114. #define UICOUNT 3
  115.  
  116. /* For our ILBM frames */
  117. struct ILBMInfo  *ilbms[UICOUNT]  = { NULL };
  118.  
  119.  
  120. /* 
  121.  * MAIN 
  122.  */
  123. void main(int argc, char **argv)
  124.    {
  125. #ifdef SAVECHANGES
  126.    struct Chunk *chunk;
  127.    CamgChunk *camg;
  128.    LONG saverror;
  129. #endif
  130.    UBYTE *ilbmname=NULL, *brushname=NULL, ans, c;
  131.    BPTR lock;
  132.    LONG error;
  133.  
  134.    FromWb = argc ? FALSE : TRUE;
  135.  
  136.    if((argc<MINARGS)||(argv[argc-1][0]=='?'))
  137.     {
  138.     printf("%s\n%s\n",Copyright,usage);
  139.         bye("",RETURN_OK);
  140.     }
  141.  
  142.    switch(argc)
  143.       {
  144.       case 4:
  145.          brushname    = argv[3];
  146.       case 3:
  147.          savename    = argv[2];
  148.          ilbmname    = argv[1];
  149.          break;
  150.       }
  151.  
  152.    /* if dest not clipboard, warn if dest file already exists */
  153.    if(strcmp(savename,"-c"))
  154.     {
  155.     if(lock = Lock(savename,ACCESS_READ))
  156.         {
  157.         UnLock(lock);
  158.         printf("Dest file \"%s\" already exists.  Overwrite (y or n) ? ",
  159.             savename);
  160.         ans = 0;
  161.         while((c = getchar()) != '\n') if(!ans)  ans = c | 0x20;
  162.         if(ans == 'n')   bye("Exiting.\n",RETURN_OK);
  163.         }
  164.     }
  165.         
  166.    /* Open Libraries */
  167.  
  168.    if(!(IntuitionBase = OpenLibrary("intuition.library", 0)))
  169.       bye("Can't open intuition library.\n",RETURN_WARN);
  170.       
  171.    if(!(GfxBase = OpenLibrary("graphics.library",0)))
  172.       bye("Can't open graphics library.\n",RETURN_WARN);
  173.  
  174.    if(!(IFFParseBase = OpenLibrary("iffparse.library",0)))
  175.       bye("Can't open iffparse library.\n",RETURN_WARN);
  176.  
  177.  
  178.  
  179. /* 
  180.  * Alloc three ILBMInfo structs (one each for defaults, screen, brush) 
  181.  */
  182.     if(!(ilbms[0] = (struct ILBMInfo *)
  183.     AllocMem(UICOUNT * sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR))) 
  184.         bye(nomem,RETURN_FAIL);
  185.     else 
  186.     {
  187.     ilbms[BRU] = ilbms[0] + 1;
  188.     ilbms[SCR] = ilbms[0] + 2;
  189.     }
  190.  
  191. /*
  192.  * Here we set up default ILBMInfo fields for our
  193.  * application's frames.
  194.  * Above we have defined the propery and collection chunks
  195.  * we are interested in (some required like BMHD)
  196.  * Since all of our frames are for ILBM's, we'll initialize
  197.  * one default frame and clone the others from it.
  198.  */
  199.     ilbms[DEF]->ParseInfo.propchks    = ilbmprops;
  200.     ilbms[DEF]->ParseInfo.collectchks    = ilbmcollects;
  201.     ilbms[DEF]->ParseInfo.stopchks    = ilbmstops;
  202.  
  203.     ilbms[DEF]->windef    = &mynw;
  204. /* 
  205.  * Initialize our working ILBM frames from our default one
  206.  */
  207.     *ilbms[SCR] = *ilbms[DEF];    /* for our screen */
  208.     *ilbms[BRU] = *ilbms[DEF];    /* for our brush  */
  209.  
  210. /* 
  211.  * Alloc two IFF handles (one for screen frame, one for brush frame) 
  212.  */
  213.     if(!(ilbms[SCR]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL);
  214.     if(!(ilbms[BRU]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL);
  215.  
  216. /* Load and display an ILBM
  217.  */
  218.     if(error = showilbm(ilbms[SCR],ilbmname))
  219.     {
  220.     printf("Can't load background \"%s\"\n",ilbmname);
  221.     bye("",RETURN_WARN);
  222.     }
  223.  
  224.     /* These were set up by our successful showilbm() above */
  225.     win = ilbms[SCR]->win;    /* our window */
  226.     wrp = ilbms[SCR]->wrp;    /* our window's RastPort */
  227.     scr = ilbms[SCR]->scr;    /* our screen */
  228.     vp  = ilbms[SCR]->vp;        /* our screen's ViewPort */
  229.  
  230.     ScreenToFront(scr);
  231.  
  232.  
  233.  /* Now let's load a brush and blit it into the window
  234.   */
  235.     if(brushname)
  236.     {
  237.     if (error = loadbrush(ilbms[BRU],brushname))
  238.         {
  239.         printf("Can't load brush \"%s\"\n",brushname);
  240.         bye("",RETURN_WARN);
  241.         }
  242.     else    /* Success */
  243.         {
  244.         D(bug("About to Blt bitmap $%lx to rp $%lx, w=%ld h=%ld\n",
  245.         ilbms[BRU]->brbitmap,wrp,ilbms[BRU]->Bmhd.w,ilbms[BRU]->Bmhd.h));
  246.             BltBitMapRastPort(ilbms[BRU]->brbitmap,0,0,
  247.                              wrp,0,0,
  248.                              ilbms[BRU]->Bmhd.w, ilbms[BRU]->Bmhd.h,
  249.                              0xC0);
  250.              }
  251.     }
  252.  
  253. #ifdef SAVECHANGES
  254.  
  255.  /* This code is an example for Read/Modify/Write programs
  256.   *
  257.   * We copy off the parsed chunks we want to preserve,
  258.   * close the IFF read file, reopen it for write,
  259.   * and save a new ILBM which
  260.   * will include the chunks we have preserved, but
  261.   * with newly computed and set-up BMHD, CMAP, and CAMG.
  262.   */ 
  263.  
  264.    if(!(ilbms[SCR]->ParseInfo.copiedchunks =
  265.     copychunks(ilbms[SCR]->ParseInfo.iff,
  266.            ilbmprops, ilbmcollects,
  267.            MEMF_PUBLIC)))
  268.         printf("error cloning chunks\n");
  269.    else
  270.     {
  271.         /* we can close the file now */
  272.        closeifile(ilbms[SCR]);
  273.  
  274.        printf("Test of copychunks and findchunk:\n");
  275.  
  276.        /* Find copied CAMG chunk if any */
  277.        if(chunk = findchunk(ilbms[SCR]->ParseInfo.copiedchunks,ID_ILBM,ID_CAMG))
  278.         {
  279.         camg = (CamgChunk *)chunk->ch_Data;
  280.         printf("CAMG: $%08lx\n",camg->ViewModes);
  281.         }
  282.         else printf("No CAMG found\n");
  283.  
  284.        /* Find copied CRNG chunks if any */
  285.        if(chunk = findchunk(ilbms[SCR]->ParseInfo.copiedchunks,ID_ILBM,ID_CRNG))
  286.         {
  287.            while((chunk)&&(chunk->ch_ID == ID_CRNG))
  288.         {
  289.         printf("Found a CRNG chunk\n");
  290.         chunk = chunk->ch_Next;
  291.         }
  292.         }
  293.        else printf("No CRNG chunks found\n");
  294.     }
  295.  
  296.     printf("\nAbout to save screen as %s, adding NAME and AUTH chunks\n",
  297.         savename);
  298.  
  299.     if(saverror = screensave(ilbms[SCR], ilbms[SCR]->scr,
  300.                 ilbms[SCR]->ParseInfo.copiedchunks,
  301.                 newchunks,
  302.                 savename))
  303.             printf("%s\n",IFFerr(saverror));
  304.  
  305. #endif
  306.  
  307.    Done = FALSE;
  308.    while(!Done)
  309.       {
  310.       Wait(1<<win->UserPort->mp_SigBit);
  311.       chkmsg();
  312.       }
  313.  
  314.  
  315.    cleanup();
  316.    exit(RETURN_OK);
  317.    }
  318.  
  319.  
  320. void chkmsg(void)
  321.     {
  322.     LONG  error;
  323.     ULONG class;
  324.     UWORD code;
  325.     WORD  mousex, mousey;
  326.  
  327.     while(msg = (struct IntuiMessage *)GetMsg(win->UserPort))
  328.     {
  329.     class = msg->Class;
  330.           code  = msg->Code;
  331.           mousex = msg->MouseX;
  332.           mousey = msg->MouseY;
  333.  
  334.           ReplyMsg(msg);
  335.           switch(class)
  336.            {
  337.         case MOUSEBUTTONS:
  338.         switch(code)
  339.         {
  340.         /* emulate a close gadget */
  341.         case SELECTDOWN:
  342.            if((mousex < 12)&&(mousey < 12))    Done = TRUE;
  343.            break;
  344.         default:
  345.            break;
  346.         }
  347.             case VANILLAKEY:
  348.             switch(code)
  349.                    {
  350.         /* also quit on CTRL-C, CTRL-D, or q */
  351.                    case 'q': case 0x04: case 0x03:
  352.                   Done = TRUE;
  353.                   break;
  354.         case 0x10:    /* CTRL-p means print */
  355.  
  356.           /* Print the whole screen */
  357.           if(error=screendump(ilbms[SCR]->scr,
  358.                 0,0,
  359.                 ilbms[SCR]->scr->Width,
  360.                 ilbms[SCR]->scr->Height,
  361.                 0,0))
  362.             printf("Screendump printer error=%ld\n",error);
  363.           break;
  364.             
  365.                    default:
  366.                   break;
  367.         }
  368.             default:
  369.             break;
  370.             }
  371.           }
  372.     }
  373.  
  374.  
  375. void bye(UBYTE *s,int error)
  376.    {
  377.    if((*s)&&(!FromWb)) printf("%s\n",s);
  378.    cleanup();
  379.    exit(error);
  380.    }
  381.  
  382.  
  383. void cleanup()
  384.    {
  385.    if(ilbms[SCR])
  386.     {
  387.        if(ilbms[SCR]->scr)        unshowilbm(ilbms[SCR]);
  388. #ifdef SAVECHANGES
  389.        freechunklist(ilbms[SCR]->ParseInfo.copiedchunks);
  390. #endif
  391.        if(ilbms[SCR]->ParseInfo.iff)    FreeIFF(ilbms[SCR]->ParseInfo.iff);
  392.     }
  393.  
  394.    if(ilbms[BRU])
  395.     {
  396.        if(ilbms[BRU]->brbitmap)    unloadbrush(ilbms[BRU]);
  397.        if(ilbms[BRU]->ParseInfo.iff)     FreeIFF(ilbms[BRU]->ParseInfo.iff);
  398.     }
  399.  
  400.    if(ilbms[0])
  401.     {
  402.     FreeMem(ilbms[0],UICOUNT * sizeof(struct ILBMInfo));
  403.     }
  404.  
  405.    if(GfxBase)          CloseLibrary(GfxBase);
  406.    if(IntuitionBase) CloseLibrary(IntuitionBase);
  407.    if(IFFParseBase)  CloseLibrary(IFFParseBase);
  408.    }
  409.